#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef UNIX
#include <kvm.h>
#endif
#include <sys/param.h>
#ifdef UNIX
#include <sys/sysctl.h>
#include <sys/user.h>
#endif
#include <fcntl.h> 
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "typedef.h"
#include "common.h"

#define BUF_LEN (1024)

static char buffer[BUF_LEN];

extern char** cmd_getsegs(char* s);
extern void cmd_free(char** p);

static void sig_handle(int id);

int os_isrunning(int pid)
{
#ifdef UNIX
    static kvm_t *kd;
    struct kinfo_proc *p;
    int i, n_processes;

    if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null", O_RDONLY, "kvm_open")) == NULL)
    {
	  	return TRUE;
    }
    else
    {
    	p = kvm_getprocs(kd, KERN_PROC_PROC, 0, &n_processes);
    	for (i = 0; i < n_processes; i++)
    	{
    		if (pid == p[i].ki_pid)
    		{
    			return TRUE;
    		}
    	}

    	kvm_close(kd);
    }
#endif
    return FALSE;
}

/*
 * By Tuwei
 * Here is big problem which is the father process cannot
 * get the return value of the child process. so we cannot
 * know the command itself is right or not.
 *
 * in the next version.we need to add the waitpid() function
 * which can tell the result of the child process. but then
 * we should use the multi-process technology.
 */
int os_run(char* command)
{
#ifdef UNIX
	int ret = -1;
	char** p = cmd_getsegs(command);
	if (p == NULL)
	{
		return -1;
	}

	signal(SIGCHLD, sig_handle);

	pid_t pid = fork();
	if (pid == 0)
	{
		if (execvp(p[0], p) == -1)
		{
			exit(-1);
		}
	}
	else if (pid > 0)
	{
		ret = pid;
	}
	else
	{
		ret = -1;
	}

	cmd_free(p);

	return ret;
#endif
}

void sig_handle(int id)
{
#ifdef UNIX
	pid_t pid;
	int   stat;

	while(pid = waitpid( -1, &stat, WNOHANG) > 0)
	{
		printf("Process Terminated : %d\n", pid);
	}
#endif
}
